abstract class List[Element] {
  def map[Tgt](fun: Element => Tgt): List[Tgt]
}

abstract class Cons[Element] extends List[Element] {
  val hd: Element
  val tl: List[Element]
    
  def map[Tgt](fun: Element => Tgt) = new Cons[Tgt]{
    val hd: Tgt = fun(Cons.this.hd)
    val tl: List[Tgt] = Cons.this.tl.map[Tgt](fun)
  }
}

class Nil[Element] extends List[Element] {
  def map[Tgt](fun: Element => Tgt) = new Nil[Tgt]
}